﻿scene.mesh.label = (function ($, undefined)
{
    var _container = null;
    var _scene = null;
    
    var _mouse = { x: 0, y: 0 }, INTERSECTED;
    var _sprite;
    var _canvas, _context, _texture;

    var init = function ($container, scene)
    {
        _container = $container;
        _scene = scene;
        
        // create a canvas element
        _canvas = document.createElement('canvas');
        _context = _canvas.getContext('2d');
        _context.font = "Bold 20px Arial";
        _context.fillStyle = "rgba(0,0,0,0.95)";
        _context.fillText('Hello, world!', 4, 2);

        // canvas contents will be used for a texture
        _texture = new THREE.Texture(_canvas);
        _texture.needsUpdate = true;

        var spriteMaterial = new THREE.SpriteMaterial({
            map: _texture,
            useScreenCoordinates: true,
            alignment: THREE.SpriteAlignment.topRight
        });

        _sprite = new THREE.Sprite(spriteMaterial);
        _sprite.scale.set(200, 100, 1.0);
        _sprite.position.set(10, 10, 0);
        _scene.add(_sprite);

        _container.mousemove(function (event) {
            _onDocumentMouseMove(event);
        });
    };
    
    var destroy = function ()
    {
    };

    var updateLabel = function(camera)
    {
        // create a Ray with origin at the mouse position and direction into the scene (camera direction)
        var vector = new THREE.Vector3(_mouse.x, _mouse.y, 1);
        
        // initialize object to perform world/screen calculations
        var projector = new THREE.Projector();
        projector.unprojectVector(vector, camera);
        
        var ray = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());

        // create an array containing all objects in the scene with which the ray intersects
        var intersects = ray.intersectObjects(_scene.children);

        // INTERSECTED = the object in the scene currently closest to the camera 
        //		and intersected by the Ray projected from the mouse position 	

        // if there is one (or more) intersections
        if (intersects.length > 0) {
            // if the closest object intersected is not the currently stored intersection object
            if (intersects[0].object != INTERSECTED) {
                // restore previous intersection object (if it exists) to its original color
                if (INTERSECTED) {
                    INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
                }
                
                // store reference to closest object as current intersection object
                INTERSECTED = intersects[0].object;
                // store color of closest object (for later restoration)
                INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
                // set a new color for closest object
                INTERSECTED.material.color.setHex(0x00aa00);

                // update text, if it has a "identifier" field.
                if (intersects[0].object.identifier) {
                    _context.clearRect(0, 0, 640, 480);

                    var text = intersects[0].object.identifier;
                    _context.fillText(text, 4, 20);
                }
                else {
                    _context.clearRect(0, 0, 300, 300);
                }
                
                _texture.needsUpdate = true;
            }
        }
        else // there are no intersections
        {
            // restore previous intersection object (if it exists) to its original color
            if (INTERSECTED) {
                INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
            }
            
            // remove previous intersection object reference
            //     by setting current intersection object to "nothing"
            INTERSECTED = null;
            _context.clearRect(0, 0, 300, 300);
            _texture.needsUpdate = true;
        }
    };

    var _onDocumentMouseMove = function (event)
    {
        // update sprite position
        _sprite.position.set(event.offsetX-10, event.offsetY-10, 0);

        // get the DOM element to attach to
        var width = _container.width(),
            height = _container.height();

        // update the mouse variable
        _mouse.x = (event.offsetX / width) * 2 - 1;
        _mouse.y = -(event.offsetY / height) * 2 + 1;
    };

    // public API
    return {
        init: init,
        destroy: destroy,
        updateLabel: updateLabel
    };
})(jQuery);